package com.watson.nettydemo.demo01;

import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * @author watson
 * @date 2021/8/4 13:53
 * @Description: 自定义服务端
 * 需求；核心义务处理逻辑
 * 用户提交一个请求后，在浏览器上就会看到hello netty world
 **/
public class SomeServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 当Channel中有来自客户端的数据时就会触发该方法的执行
     *
     * @param ctx 上下文对象
     * @param msg 来自于客户端（channel）的数据
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("msg = " + msg.getClass());
        System.out.println("客户端地址 = " + ctx.channel().remoteAddress());


        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            System.out.println(request.method().name());
            System.out.println(request.uri());

            if ("/favicon.ico".equals(request.uri())) {
                // springmvc 已经帮我们处理了
                System.out.println("不处理/favicon.ico");
                //favicon.ico 图标
                return;
            }
            Map map = new HashMap();
            map.put("dsf", "das");
            map.put("sd", "das");
            String string = JSON.toJSONString(map);
            //构造response响应体
//            ByteBuf body = Unpooled.copiedBuffer("hello netty world", CharsetUtil.UTF_8);
            ByteBuf body = Unpooled.copiedBuffer(string, CharsetUtil.UTF_8);
            //生成响应对象
            DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, body);
            //获取到response的头部进行初始化
            HttpHeaders headers = httpResponse.headers();
//            headers.set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            headers.set(HttpHeaderNames.CONTENT_TYPE, "application/json");
            headers.set(HttpHeaderNames.CONTENT_LENGTH, body.readableBytes());

            //将响应对象写入到channel
//            ctx.write(httpResponse);
//            ctx.flush();

            ctx.writeAndFlush(httpResponse)
                    //添加监听器，相应提发送完毕则直接将channel关闭
                    .addListener(ChannelFutureListener.CLOSE);

        }
    }

    /**
     * 当Channel中的数据在处理过程中出现异常时会触发该方法的执行
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        //请求关闭
        ctx.close();
    }
}
